/*****************************************************************************
	SNEGA UTILITIES 0.7a
	Copyright (C) 2009, Xiaohan Tian (snega0223)
	
	http://code.google.com/p/snega-utilities/
	
	This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License(LGPL) as
	published by the Free Software Foundation, either version 3 of the 
	License, or(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.
	
	You should have received a copy of the GNU Lesser General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/

package org.sng.util.web.elmt;

import java.io.*;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;

import org.sng.util.var.*;
import org.sng.util.web.*;

public class RuntimeEnvironment {
	
	private ServletOutputStream m_out;
	private HttpServletRequest m_request;
	private HttpServletResponse m_response;
	private Node m_root;
	
	private WebPageMaker m_maker;
	
	private HashMap<String, SVoid> m_varMap;
	
	private StringBuffer m_endHeadContent;
	private StringBuffer m_startBodyContent;
	private StringBuffer m_endBodyContent;
	private StringBuffer m_postList;
	private StringBuffer m_javascript;
	private StringBuffer m_html;
	
	private String m_url;
	
	private int m_browserType;

	public RuntimeEnvironment()
	{
		this.m_request = null;
		this.m_response = null;
		
		this.m_out = null;
		this.m_root = null;
		this.m_maker = null;
		
		this.m_endHeadContent = new StringBuffer();
		this.m_startBodyContent = new StringBuffer();
		this.m_endBodyContent = new StringBuffer();
		this.m_postList = new StringBuffer();
		this.m_javascript = new StringBuffer();
		this.m_html = new StringBuffer();
		
		this.m_browserType = 0;
		
		this.m_varMap = new HashMap<String, SVoid>();
	}
	
	public RuntimeEnvironment(HttpServletRequest request, HttpServletResponse response, WebPageMaker maker, Node root)
	{
		try {
			this.m_request = request;
			this.m_response = response;
			
			this.m_out = response.getOutputStream();
			this.m_root = root;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			
			this.m_request = null;
			this.m_response = null;
			
			this.m_out = null;
		} finally {
			this.m_maker = maker;
			
			this.m_endHeadContent = new StringBuffer();
			this.m_startBodyContent = new StringBuffer();
			this.m_endBodyContent = new StringBuffer();
			this.m_postList = new StringBuffer();
			this.m_javascript = new StringBuffer();
			this.m_html = new StringBuffer();
			
			this.m_browserType = 0;
			
			this.m_varMap = new HashMap<String, SVoid>();
			
			this.m_varMap.put("Request", new RequestObject(this.m_request));
		}
	}
	
	public Node GetRoot()
	{
		return this.m_root;
	}
	
	public WebPageMaker GetMaker()
	{
		return this.m_maker;
	}
	
	public Node $(String id)
	{
		return this.m_root.GetNodeById(id);
	}
	
	public SString $QueryString(String id)
	{
		return new SString(this.m_request.getParameter(id));
	}
	
	public NodeButton $Button(String id)
	{
		return (NodeButton)this.m_root.GetNodeById(id);
	}
	
	public NodeTextField $TextField(String id)
	{
		return (NodeTextField)this.m_root.GetNodeById(id);
	}
	
	public NodeTextBox $TextBox(String id)
	{
		return (NodeTextBox)this.m_root.GetNodeById(id);
	}
	
	public NodeTextArea $TextArea(String id)
	{
		return (NodeTextArea)this.m_root.GetNodeById(id);
	}
	
	public NodeContainer $Container(String id)
	{
		return (NodeContainer)this.m_root.GetNodeById(id);
	}
	
	public NodeVariable $Variable(String id)
	{
		return (NodeVariable)this.m_root.GetNodeById(id);
	}
	
	public NodeSelect $Select(String id)
	{
		return (NodeSelect)this.m_root.GetNodeById(id);
	}
	
	public void OpenNewWindow(String url)
	{
		this.AppendJavascript("window.open(\"" + url + "\");");
	}
	
	public void RefreshWindow()
	{
		this.AppendJavascript("window.location.reload();");
	}
	
	public SArray CreateArray(String id, int i)
	{
		SArray o = new SArray(i);
		
		this.m_varMap.put(id, o);
		
		return o;
	}
	
	public SHashMap CreateHashMap(String id)
	{
		SHashMap o = new SHashMap();
		
		this.m_varMap.put(id, o);
		
		return o;
	}
	
	public void PushVar(String id, SVoid o)
	{
		this.m_varMap.put(id, o);
	}
	
	public void PushVar(String id, int i)
	{
		this.m_varMap.put(id, new SInt(i));
	}
	
	public void PushVar(String id, String s)
	{
		this.m_varMap.put(id, new SString(s));
	}
	
	public void PushVar(String id, StringBuffer s)
	{
		this.m_varMap.put(id, new SString(s));
	}
	
	public void PushVar(String id, int [] array)
	{
		SArray o = new SArray(array.length);
		
		for (int i = 0; i < array.length; i++) {
			o.PushVar(i, array[i]);
		}
		
		this.m_varMap.put(id, (SVoid)o);
	}
	
	public void PushVar(String id, String [] array)
	{
		SArray o = new SArray(array.length);
		
		for (int i = 0; i < array.length; i++) {
			o.PushVar(i, array[i]);
		}
		
		this.m_varMap.put(id, (SVoid)o);
	}
	
	public void PushVar(String id, SVoid [] array)
	{
		SArray o = new SArray(array.length);
		
		for (int i = 0; i < array.length; i++) {
			o.PushVar(i, array[i]);
		}
		
		this.m_varMap.put(id, (SVoid)o);
	}
	
	public SVoid GetVar(String id)
	{
		return this.m_varMap.get(id);
	}
	
	public HttpServletRequest GetRequest()
	{
		return this.m_request;
	}
	
	public String GetEventId()
	{
		return this.m_request.getParameter("id");
	}
	
	public String GetEvent()
	{
		return this.m_request.getParameter("event");
	}
	
	public Node GetEventNode()
	{
		return this.m_root.GetNodeById(this.GetEventId());
	}
	
	public HttpServletResponse GetResponse()
	{
		return this.m_response;
	}
	
	public void Out(String s)
	{
		try {
			m_out.print(s);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void Response()
	{
		// Build container relationship
		Node [] o = this.GetRoot().GetNodeArrayByType("container");
		for (int i = 0; o != null && i < o.length; i++)
		{
			//SLog.println(o[i].GetProperty("id").GetString(this));
			((NodeContainer)(o[i])).RegisterChildrenInPage(this);
		}
		
		// Output
		this.Out("<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response><JS><![CDATA[");
		
		this.Out(this.GetJavascript().toString());
		
		this.Out("GetPostList=function(){var para=new $ParaPair();para.add(\"BrowserType\", getClientBrowser());");		// Rebuild post list
		this.Out(this.GetPostList().toString());
		this.Out("return para;};");
		
		this.Out("]]></JS><HTML><![CDATA[");
		this.Out("]]></HTML></Response>");
	}

	public StringBuffer GetEndHeadContent() {
		return this.m_endHeadContent;
	}

	public void AppendEndHeadContent(StringBuffer headContent) {
		this.m_endHeadContent.append(headContent);
	}
	
	public void AppendEndHeadContent(String headContent) {
		this.m_endHeadContent.append(headContent);
	}

	public StringBuffer GetStartBodyContent() {
		return this.m_startBodyContent;
	}

	public void AppendStartBodyContent(StringBuffer bodyContent) {
		this.m_startBodyContent.append(bodyContent);
	}
	
	public void AppendStartBodyContent(String bodyContent) {
		this.m_startBodyContent.append(bodyContent);
	}

	public StringBuffer GetEndBodyContent() {
		return this.m_endBodyContent;
	}

	public void AppendEndBodyContent(StringBuffer bodyContent) {
		this.m_endBodyContent.append(bodyContent);
	}
	
	public void AppendEndBodyContent(String bodyContent) {
		this.m_endBodyContent.append(bodyContent);
	}
	
	public StringBuffer GetPostList() {
		return this.m_postList;
	}

	public void AppendPostList(StringBuffer s) {
		this.m_postList.append(s);
	}
	
	public void AppendPostList(String s) {
		this.m_postList.append(s);
	}
	
	public void AppendPostList(String id, String value) {
		this.m_postList.append("para.add(\"" + id + "\", " + value + ");");
	}
	
	public StringBuffer GetJavascript() {
		return this.m_javascript;
	}
	
	public void AppendJavascript(StringBuffer s) {
		this.m_javascript.append(s);
	}
	
	public void AppendJavascript(String s) {
		this.m_javascript.append(s);
	}
	
	public StringBuffer GetHtml() {
		return this.m_html;
	}
	
	public void AppendHtml(StringBuffer s) {
		this.m_html.append(s);
	}
	
	public void AppendHtml(String s) {
		this.m_html.append(s);
	}
	
	public String GetUrl() {
		return m_url;
	}

	public void SetUrl(String url) {
		this.m_url = url;
	}
	
	public void SetBrowserType(int i) {
		this.m_browserType = i;
	}
	
	public int GetBrowserType() {
		return this.m_browserType;
	}
	
}
